package com.kotiln.lgc.lib_network.thread;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @date 2021/3/3
 */
public class ThreadPool implements IThreadPool {
    private final Builder builder;
    private ThreadPoolExecutor threadPoolExecutor;
    private ThreadFactory mThreadFactory;

    protected ThreadPool(Builder builder) {
        this.builder = builder;
        createThreadPool();
    }

    @Override
    public void createThreadPool() {

        if (builder.corePoolSize > 0 && builder.maximumPoolSize > 0 && builder.keepAliveTime > 0 && builder.capacity > 0) {
            threadPoolExecutor = new ThreadPoolExecutor(builder.corePoolSize, builder.maximumPoolSize, builder.keepAliveTime, builder.timeUnit, new LinkedBlockingQueue<Runnable>(builder.capacity));
        }
    }

    @Override
    public void setThreadFactory(ThreadFactory factory) {

        if (null == factory) {
            throw new NullPointerException("factory is nul");
        }
        this.mThreadFactory = factory;
        threadPoolExecutor.setThreadFactory(this.mThreadFactory);
    }


    @Override
    public void startThread(Runnable runnable) {
        if (threadPoolExecutor == null) {
            throw new RuntimeException("please call createThreadPool()");
        }
        if (mThreadFactory == null) {
            throw new NullPointerException("ThreadFactory is null");
        }
        threadPoolExecutor.execute(runnable);
    }

    public static abstract class Builder {
        protected int corePoolSize = 0;
        protected int maximumPoolSize = 0;
        protected int keepAliveTime = 0;
        protected TimeUnit timeUnit = TimeUnit.MILLISECONDS;
        protected int capacity = 0;//存放线程的最大数

        public Builder setCorePoolSize(int corePoolSize) {
            this.corePoolSize = corePoolSize;
            return this;
        }

        public Builder setMaximumPoolSize(int maximumPoolSize) {
            this.maximumPoolSize = maximumPoolSize;
            return this;
        }

        public Builder setKeepAliveTime(int keepAliveTime) {
            this.keepAliveTime = keepAliveTime;
            return this;
        }

        public Builder setTimeUnit(TimeUnit timeUnit) {
            this.timeUnit = timeUnit;
            return this;
        }

        public Builder setCapacity(int capacity) {
            this.capacity = capacity;
            return this;
        }

        /**
         * 返回创建对象
         *
         * @return 线程对象
         */
        public abstract ThreadPool create();
    }
}
